package application.parasitic;

import application.anno.Group;
import application.exception.NotFoundNecessaryAnnotationException;
import application.manager.ParasiticManagerStack;
import javafx.scene.layout.Pane;
import lombok.Getter;
import lombok.Setter;

import java.io.IOException;

/**
 * 寄生布局，他利用Layout注解填充布局
 * 提供jumpTo方法使得布局与布局之间可以相互跳转
 * 通过Group注解注册到指定组中
 * 提供一个release方法结束寄生
 * 提供一个back方法，提供返回前一个寄生布局
 * 使用MainLayout
 */
public class ParasiticLayout {
    /**
     * 布局对象
     */
    @Getter
    @Setter
    private Pane pane;

    /**
     * 是否处于活动状态，true表示活动状态，即存在于显示状态，false表示为非活动状态，即存在于非显示状态。
     */
    @Getter
    private boolean isActivity;

    /**
     * 释放寄生，销毁此寄生布局
     */
    public void release() {
        Class<? extends ParasiticLayout> aClass = this.getClass();
        Group group = aClass.getAnnotation(Group.class);
        if (group == null) {
            try {
                throw new NotFoundNecessaryAnnotationException("Not found Group annotation, can not get group information");
            } catch (NotFoundNecessaryAnnotationException e) {
                e.printStackTrace();
            }
            return;
        }
        ParasiticManagerStack parasiticManagerStack = ParasiticManagerStack.getInstance();
        ParasiticLayout back = parasiticManagerStack.back(group.value());
        Pane pane = (Pane) this.pane.getParent();
        pane.getChildren().clear();
        pane.getChildren().add(back.pane);
        this.pane.setVisible(false);
        parasiticManagerStack.release(group.value(), this);
        unregisterReceiver();
    }

    /**
     * 退回至上一个寄生布局
     */
    public void back() {
        Class<? extends ParasiticLayout> aClass = this.getClass();
        Group group = aClass.getAnnotation(Group.class);
        if (group == null) {
            try {
                throw new NotFoundNecessaryAnnotationException("Not found Group annotation, can not get group information");
            } catch (NotFoundNecessaryAnnotationException e) {
                e.printStackTrace();
            }
            return;
        }
        String value = group.value();
        ParasiticManagerStack parasiticManagerStack = ParasiticManagerStack.getInstance();
        ParasiticLayout back = parasiticManagerStack.back(value);
        Pane pane = (Pane) this.pane.getParent();
        pane.getChildren().clear();
        pane.getChildren().add(back.getPane());
        parasiticManagerStack.pushForward(group.value(), this);
        this.pane.setVisible(false);
        unregisterReceiver();
    }

    /**
     * 寄生布局的跳转
     *
     * @param parasiticLayout 当前寄生布局对象
     * @param cls             跳转至目标寄生布局的类对象
     */
    public void jumpTo(ParasiticLayout parasiticLayout, Class<? extends ParasiticLayout> cls) {
        ParasiticManagerStack parasiticManagerStack = ParasiticManagerStack.getInstance();
        Group annotation = cls.getAnnotation(Group.class);
        if (annotation == null) {
            try {
                throw new NotFoundNecessaryAnnotationException("Not found Group annotation, can not get group information");
            } catch (NotFoundNecessaryAnnotationException e) {
                e.printStackTrace();
            }
        }
        try {
            ParasiticLayout register = parasiticManagerStack.register(cls);
            Pane pane = (Pane) this.pane.getParent();
            pane.getChildren().clear();
            pane.getChildren().add(register.getPane());
            register.pane.setVisible(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        parasiticManagerStack.pushBack(annotation.value(), parasiticLayout);
    }

    /**
     * 设置此寄生布局的显示状态
     *
     * @param visible
     */
    public void setVisible(boolean visible) {
        pane.setVisible(visible);
        this.isActivity = visible;
    }

    /**
     * 子类重写此类并且在其上方加上FXML注解，这样可以在加载资源的时候，初始化窗口Controller
     */
    protected void initialize() {
        registerReceiver();
    }

    protected void registerReceiver() {

    }

    protected void unregisterReceiver() {

    }
}
